package controllers.user

import controllers.{checkAdmin, checkLogin}
import models.outstock._
import play.api.Logging
import play.api.data.Forms._
import play.api.data._
import play.api.libs.json._
import play.api.mvc._
import services.intermediate.{GetDataFromGy, SendOutStockSum, SumOutStockRev}
import services.{OutStockPostParameters, TestJson}
import utiliy.OutFilterConfig

import java.time.LocalDateTime
import javax.inject.Inject
import scala.concurrent.{ExecutionContext, Future}

case class ListJson(page: Int, limit: Int, title: String)

/**
 * 管易与金蝶销售数据同步与汇总状态查询接口
 *
 * @param cc
 * @param sumOSR  汇总销售发货单
 * @param sendOSS 发送销售发货汇总单
 * @param osrRepo 销售发货单ORM
 * @param ossRepo 销售发货汇总单ORM
 * @param ofc     筛选过滤设置
 * @param exec
 * @param parser
 */
class KisOutStockController @Inject()(
                                       cc: ControllerComponents,
                                       sumOSR: SumOutStockRev,
                                       sendOSS: SendOutStockSum,
                                       osrRepo: OutStockRevRepository,
                                       ossRepo: OutStockSumRepository,
                                       ofc: OutFilterConfig,
                                       getDFGY: GetDataFromGy,
//                                       gyQimen: GyQimenService
                                     )(
                                       implicit exec: ExecutionContext,
                                       parser: BodyParsers.Default
                                     )
  extends AbstractController(cc) with Logging {
  def index = checkLogin(parser, exec,"wuyang") {
    Ok("kisUI Home Page")
  }

  def testJson = Action { implicit request =>
    val place = request.body.asJson.getOrElse(Json.obj("page" -> 1, "limit" -> 10))
    Ok(TestJson.testJson(place("page").as[Int], place("limit").as[Int]))
  }

  /**
   * 销售发货单中间处理服务访问页面
   *
   * @return
   */
  def outstock() = checkLogin(parser, exec,permission = "wuyang").async { implicit request =>
    osrRepo.osrStockCodes.map { f =>
      Ok(
        views.html.layui.outstock(
          "outstock",
          f.map(s =>
            Tuple2(
              s,
              ofc.getOutStockName(s).getOrElse(s))).toList
        )
      )
    }
  }

  val parameters = Form(
    mapping(
      "page" -> number,
      "limit" -> number,
      "sdate" -> nonEmptyText,
      "status" -> default(number, (0)),
      "p1" -> default(text, ("")),
      "p2" -> default(text, ("")),

    )(OutStockPostParameters.apply)(OutStockPostParameters.unapply)
  )

  /**
   *
   * @param id
   * @param OutStockSumId
   * @param FEntity
   * @param FDate        "2019-06-12 10:51:55",
   * @param FGYBillNo    models.CharField(max_length=20,unique=True)      #"SDO128041097656",
   * @param FShopNumber  models.CharField(max_length=20)  # "C030037",
   * @param FStockNumber models.CharField(max_length=20)  # "SCM02",
   * @param SumStatus    models.IntegerField(default=0)  # 汇总状态（0：未汇总，1：准备汇总，2：完成汇总）
   */
  case class LayuiOutStockRecive(id: Option[Int] = Some(0),
                                 OutStockSumId: String = "",
                                 FEntity: Boolean = false,
                                 FDate: LocalDateTime,
                                 FGYBillNo: String,
                                 FShopNumber: String,
                                 FStockNumber: String,
                                 SumStatus: String = "0",
                                 //osrFEntityInfo:Option[String] = None,
                                )

  def outStockRevView = checkLogin(parser, exec,"wuyang").async { implicit request =>
    val p: OutStockPostParameters = parameters.bindFromRequest().fold(
      formWithErrors => {
        logger.error("outStockRevView is application/badform")
        BadRequest(formWithErrors.toString)
        OutStockPostParameters()
      },
      f => {
        println("outStockRevView is application/form")
        //implicit val formDataWrite = Json.writes[OutStockPostParameters]
        OutStockPostParameters(f.page - 1, f.limit, f.sdate, f.status, f.p1, f.p2)
      }
    )
    logger.info(s"outStockRevView form = ${p.toString()}")
    val res = osrRepo.list(p)
    //println(s"page = $page")
    implicit val tableResJson = Json.format[LayuiOutStockRecive]
    res.map { page =>
      val data = page._1.map(i =>
        LayuiOutStockRecive(
          id = i.osrid,
          OutStockSumId = if (i.osrOutStockSumId.isEmpty) "" else s"XSDO${i.osrOutStockSumId.getOrElse(0)}",
          FEntity = i.osrFEntity,
          FDate = i.osrFDate.toLocalDateTime,
          FGYBillNo = i.osrFGYBillNo,
          FShopNumber = i.osrFShopNumber,
          FStockNumber = i.osrFStockNumber,
          SumStatus = models.outstock.OutStockRev.strSumStatus(i))
      )
      Ok(
        Json.obj(
          "code" -> 0,
          "message" -> "",
          "count" -> page._2,
          "data" -> Json.toJson(data)
        )
      )
    }
  }

  /**
   * 销售汇总单返回前端数据格式
   *
   * @param id
   * @param ossFDate        单据日期
   * @param ossFGYBillNo    单据编号
   * @param ossFShopNumber  店铺代码
   * @param ossFStockNumber 仓库代码
   * @param ossSumInfo      汇总信息
   * @param ossKDResultID   金蝶单据编号
   * @param ossResult       金蝶回传信息
   * @param ossFEntity
   * @param ossStatus       状态
   *                        case 2 => "同步成功";  case 1 => "同步失败"; case 0 => "未同步"; case _ => "异常";
   */
  case class LayuiOutStockSum(
                               id: Option[Int],
                               ossFDate: LocalDateTime,
                               ossFGYBillNo: String,
                               ossFShopNumber: String,
                               ossFStockNumber: String,
                               ossSumInfo: Option[String],
                               ossKDResultID: Option[String],
                               ossResult: Option[String],
                               ossFEntity: Boolean,
                               ossStatus: String
                             )

  /**
   * 查询 销售发货汇总单 信息
   *
   * @return 销售发货汇总单 JSON 数据
   */
  def outStockSumView = checkLogin(parser, exec,"wuyang").async { implicit request =>
    val p: OutStockPostParameters = parameters.bindFromRequest().fold(
      formWithErrors => {
        logger.error("outStockSumView is application/badform")
        BadRequest(formWithErrors.toString)
        OutStockPostParameters()
      },
      f => {
        println("outStockSumView is application/form")
        //implicit val formDataWrite = Json.writes[OutStockPostParameters]
        OutStockPostParameters(f.page - 1, f.limit, f.sdate, f.status, f.p1, f.p2)
      }
    )
    logger.info(s"outStockSumView form = ${p.toString()}")

    val res = ossRepo.list(p)
    //println(s"page = $page")
    implicit val tableResJson = Json.format[LayuiOutStockSum]
    res.map { page =>
      val data = page._1.map(i =>
        LayuiOutStockSum(
          id = i.id,
          ossFDate = i.ossFDate.toLocalDateTime,
          ossFEntity = i.ossFEntity,
          ossFShopNumber = i.ossFShopNumber,
          ossFStockNumber = i.ossFStockNumber,
          ossStatus = {
            i.ossStatus match {
              case 2 => "同步成功";
              case 1 => "同步失败";
              case 0 => "未同步";
              case _ => "异常";
            }
          },
          ossFGYBillNo = i.ossFGYBillNo,
          ossSumInfo = i.ossSumInfo,
          ossKDResultID = i.ossKDResultID,
          ossResult = i.ossResult
        )
      )
      Ok(
        Json.obj(
          "code" -> 0,
          "message" -> "",
          "count" -> page._2,
          "data" -> Json.toJson(data)
        )
      )
    }
  }

  /**
   * 汇总销售发货单
   *
   * @return 汇总结果 JSON数据
   */
  def sumOutStockRev = checkAdmin(parser, exec) { implicit request =>
    val p: OutStockPostParameters = parameters.bindFromRequest().fold(
      formWithErrors => {
        logger.error("sumOutStockRev is application/badform")
        BadRequest(formWithErrors.toString)
        OutStockPostParameters()
      },
      f => {
        println("sumOutStockRev is application/form")
        //implicit val formDataWrite = Json.writes[OutStockPostParameters]
        OutStockPostParameters(f.page - 1, f.limit, f.sdate, f.status, f.p1, f.p2)
      }
    )
    logger.info(s"sumOutStockRev form = ${p.toString()}")
    val res = sumOSR.osrSum(p)
    val data = res.map(f => Json.parse(f))
    Ok(
      Json.obj(
        "code" -> 0,
        "message" -> "",
        "count" -> data.length,
        "data" -> Json.toJson(data)
      )
    )
  }

  def sendOutStockSum = checkLogin(parser, exec,"wuyang") { implicit request =>
    val p: OutStockPostParameters = parameters.bindFromRequest().fold(
      formWithErrors => {
        logger.error("sendOutStockSum is application/badform")
        BadRequest(formWithErrors.toString)
        OutStockPostParameters()
      },
      f => {
        println("sendOutStockSum is application/form")
        //implicit val formDataWrite = Json.writes[OutStockPostParameters]
        OutStockPostParameters(f.page - 1, f.limit, f.sdate, f.status, f.p1, f.p2)
      }
    )
    logger.info(s"sendOutStockSum form = ${p.toString()}")
    val res = sendOSS.sendOSS(p)
    val data = res.map(f => Json.parse(f))
    Ok(
      Json.obj(
        "code" -> 0,
        "message" -> "",
        "count" -> data.length,
        "data" -> Json.toJson(data)
      )
    )
  }

  def ossFEntityCount = checkLogin(parser, exec,"wuyang") { implicit request =>
    val p: OutStockPostParameters = parameters.bindFromRequest().fold(
      formWithErrors => {
        logger.error("ossFEntityCount is application/badform")
        BadRequest(formWithErrors.toString)
        OutStockPostParameters()
      },
      f => {
        println("ossFEntityCount is application/form")
        //implicit val formDataWrite = Json.writes[OutStockPostParameters]
        OutStockPostParameters(f.page - 1, f.limit, f.sdate, f.status, f.p1, f.p2)
      }
    )
    logger.info(s"sendOutStockSum form = ${p.toString()}")
    val res = sendOSS.ossFEntityCount(p)
    val data = res._1.map(f => Json.parse(f))
    Ok(
      Json.obj(
        "code" -> 0,
        "message" -> "",
        "count" -> res._2,
        "data" -> Json.toJson(data)
      )
    )
  }

  def getDataFromGy1() = checkLogin(parser, exec) { implicit request =>
    val p: OutStockPostParameters = parameters.bindFromRequest().fold(
      formWithErrors => {
        logger.error("ossFEntityCount is application/badform")
        BadRequest(formWithErrors.toString)
        OutStockPostParameters()
      },
      f => {
        println("getDataFromGy is application/form")
        //implicit val formDataWrite = Json.writes[OutStockPostParameters]
        OutStockPostParameters(f.page - 1, f.limit, f.sdate, f.status, f.p1, f.p2)
      }
    )
    logger.info(s"getDataFromGy form = ${p.toString()}")
    val res = getDFGY.getDataFromGy(p)
    Ok(
      Json.obj(
        "code" -> 0,
        "message" -> "",
        "count" -> 0,
        "data" -> Json.arr()
      )
    )
  }

  val getForm = Form(
    tuple(
      "sdate" -> default(text, ("")),
      "status" -> default(text, ("")),
      "code" -> default(text, ""),
      "page" -> number,
      "limit" -> number
    )
  )

  def getDataFromGy() = Action{Ok("~~~~~~~~~~~~~")}
//  def getDataFromGy() = Action.async { implicit request =>
//    val p: OutStockPostParameters = parameters.bindFromRequest().fold(
//      formWithErrors => {
//        logger.error("getDataFromGy is application/badform")
//        BadRequest(formWithErrors.toString)
//        OutStockPostParameters()
//      },
//      f => {
//        println("getDataFromGy is application/form")
//        //implicit val formDataWrite = Json.writes[OutStockPostParameters]
//        OutStockPostParameters(f.page - 1, f.limit, f.sdate, f.status, f.p1, f.p2)
//      }
//    )
//    logger.info(s"getDataFromGy form = ${p.toString()}")
//    val code = p.p1
//    // 2022-06-01T00:00:00 ~ 2022-06-02T00:00:00
//    val date = p.sdate.split(" ~ ")
//    val start = date(0)
//    val end = date(1)
//    logger.debug(s"getDataFromGy: $start ~ $end, code: $code")
//    val res = p.p2 match {
//      case "delivery" => gyQimen.getDeliveryAt(start, end, code)
//      case "tradereturn" => gyQimen.getReturnAt(start, end, code,p.status)
//      case "tradeorder" => gyQimen.getTradeOrderAt(start, end, code)
//      case _ => Future(Seq("nothing"))
//    }
//    res.map {
//      result =>
//        Ok(
//          Json.obj(
//            "code" -> 0,
//            "message" -> "",
//            "count" -> result.length,
//            "data" -> Json.toJson(result.map(r => Json.obj("result" -> r)))
//          )
//        )
//    }
//  }
}
